---
id: failure-detection
title: Failure detection - TypeScript SDK feature guide
sidebar_label: Failure detection
description: Optimize Workflow Execution with Temporal TypeScript SDK - Set Timeouts, Retry Policies, and manage Activity Heartbeats efficiently.
toc_max_heading_level: 4
keywords:
  - typescript
  - failure detection
tags:
  - Activities
  - Workflows
  - Errors
  - Failures
  - TypeScript SDK
  - Temporal SDKs
---

This page shows how to do the following:

- [Workflow Timeouts](#workflow-timeouts)
- [Workflow retries](#workflow-retries)
- [Activity Timeouts](#activity-timeouts)
- [Activity Retry Policy](#activity-retries)
- [Activity next Retry delay](#activity-next-retry-delay)
- [Heartbeat an Activity](#activity-heartbeats)
- [Activity Heartbeat Timeout](#activity-heartbeat-timeout)

## Workflow Timeouts {#workflow-timeouts}

**How to set Workflow Timeouts using the Temporal TypeScript SDK**

Each Workflow timeout controls the maximum duration of a different aspect of a Workflow Execution.

Workflow Timeouts are set when starting a Workflow using either the Client or Workflow API.

- **[Workflow Execution Timeout](/encyclopedia/detecting-workflow-failures#workflow-execution-timeout)** - restricts the maximum amount of time that a single Workflow Execution can be executed
- **[Workflow Run Timeout](/encyclopedia/detecting-workflow-failures#workflow-run-timeout):** restricts the maximum amount of time that a single Workflow Run can last
- **[Workflow Task Timeout](/encyclopedia/detecting-workflow-failures#workflow-task-timeout):** restricts the maximum amount of time that a Worker can execute a Workflow Task

The following properties can be set on the [`WorkflowOptions`](https://typescript.temporal.io/api/interfaces/client.WorkflowOptions/) when starting a Workflow using either the Client or Workflow API:

- [`workflowExecutionTimeout​`](https://typescript.temporal.io/api/interfaces/client.WorkflowOptions/#workflowexecutiontimeout)
- [`workflowRunTimeout`](https://typescript.temporal.io/api/interfaces/client.WorkflowOptions/#workflowruntimeout)
- [`workflowTaskTimeout`](https://typescript.temporal.io/api/interfaces/client.WorkflowOptions/#workflowtasktimeout)

```typescript
await client.workflow.start(example, {
  taskQueue,
  workflowId,
  // Set Workflow Timeout duration
  workflowExecutionTimeout: '1 day',
  // workflowRunTimeout: '1 minute',
  // workflowTaskTimeout: '30 seconds',
});
```

## Workflow retries {#workflow-retries}

**How to set Workflow retries using the Temporal TypeScript SDK**

A Retry Policy can work in cooperation with the timeouts to provide fine controls to optimize the execution experience.

Use a [Retry Policy](/encyclopedia/retry-policies) to retry a Workflow Execution in the event of a failure.

Workflow Executions do not retry by default, and Retry Policies should be used with Workflow Executions only in certain situations.

The Retry Policy can be set through the [`WorkflowOptions.retry`](https://typescript.temporal.io/api/interfaces/client.WorkflowOptions/#retry) property when starting a Workflow using either the Client or Workflow API.

```typescript
const handle = await client.workflow.start(example, {
  taskQueue,
  workflowId,
  retry: {
    maximumAttempts: 3,
    maximumInterval: '30 seconds',
  },
});
```

## Activity Timeouts {#activity-timeouts}

**How to set Activity Timeouts using the Temporal TypeScript SDK**

Each Activity Timeout controls the maximum duration of a different aspect of an Activity Execution.

The following Timeouts are available in the Activity Options:

- **[Schedule-To-Close Timeout](/encyclopedia/detecting-activity-failures#schedule-to-close-timeout):** is the maximum amount of time allowed for the entire [Activity Execution](/activities#activity-execution), from when the [Activity Task](/workers#activity-task) is initially scheduled by the Workflow to when the server receives a sucessful completion for that Activity Task
- **[Start-To-Close Timeout](/encyclopedia/detecting-activity-failures#start-to-close-timeout):** is the maximum time allowed for a single [Activity Task Execution](/workers#activity-task-execution), from when the Activity Task Execution gets polled by a [Worker](/workers#worker) to when the server receives a successfull completion for that Activity Task
- **[Schedule-To-Start Timeout](/encyclopedia/detecting-activity-failures#schedule-to-start-timeout):** is the maximum amount of time that is allowed from when an [Activity Task](/workers#activity-task) is initially scheduled by the Workflow to when a [Worker](/workers#worker) polls the Activity Task Execution

An Activity Execution must have either the Start-To-Close or the Schedule-To-Close Timeout set.

The following properties can be set on the [`ActivityOptions`](https://typescript.temporal.io/api/interfaces/common.ActivityOptions) when creating Activity proxy functions using the [`proxyActivities()`](https://typescript.temporal.io/api/namespaces/workflow#proxyactivities) API:

- [`scheduleToCloseTimeout`](https://typescript.temporal.io/api/interfaces/common.ActivityOptions/#scheduletoclosetimeout)
- [`startToCloseTimeout`](https://typescript.temporal.io/api/interfaces/common.ActivityOptions/#starttoclosetimeout)
- [`scheduleToStartTimeout`](https://typescript.temporal.io/api/interfaces/common.ActivityOptions/#scheduletostarttimeout)

```typescript
const { myActivity } = proxyActivities<typeof activities>({
  scheduleToCloseTimeout: '5m',
  // startToCloseTimeout: "30s", // recommended
  // scheduleToStartTimeout: "60s",
});
```

## Activity Retry Policy {#activity-retries}

**How to set an Activity Retry Policy using the Temporal TypeScript SDK**

A Retry Policy works in cooperation with the timeouts to provide fine controls to optimize the execution experience.

Activity Executions are automatically associated with a default [Retry Policy](/encyclopedia/retry-policies) if a custom one is not provided.

To set an Activity's Retry Policy in TypeScript, assign the [`ActivityOptions.retry`](https://typescript.temporal.io/api/interfaces/common.ActivityOptions#retry) property when creating the corresponding Activity proxy function using the [`proxyActivities()`](https://typescript.temporal.io/api/namespaces/workflow#proxyactivities) API.

```typescript
const { myActivity } = proxyActivities<typeof activities>({
  // ...
  retry: {
    initialInterval: '10s',
    maximumAttempts: 5,
  },
});
```

## Activity next Retry delay {#activity-next-retry-delay}

**How to override the next Retry delay following an Activity failure using the Temporal TypeScript SDK**

The time to wait after a retryable Activity failure until the next retry is attempted is normally determined by that Activity's Retry Policy.
However, an Activity may override that duration when explicitly failing with an [`ApplicationFailure`](https://typescript.temporal.io/api/classes/common.ApplicationFailure) by setting a next Retry delay.

To override the next Retry delay for an `ApplicationFailure` thrown by an Activity in TypeScript, provide the [`nextRetryDelay`](https://typescript.temporal.io/api/interfaces/common.ApplicationFailureOptions#nextretrydelay) property on the object argument of the [`ApplicationFailure.create()`](https://typescript.temporal.io/api/classes/common.ApplicationFailure#create) factory method.

```typescript
throw ApplicationFailure.create({
  // ...
  nextRetryDelay: '15s',
});
```

## Heartbeat an Activity {#activity-heartbeats}

**How to Heartbeat an Activity using the Temporal TypeScript SDK**

An [Activity Heartbeat](/encyclopedia/detecting-activity-failures#activity-heartbeat) is a ping from the [Worker Process](/workers#worker-process) that is executing the Activity to the [Temporal Service](/clusters).
Each Heartbeat informs the Temporal Service that the [Activity Execution](/activities#activity-execution) is making progress and the Worker has not crashed.
If the Temporal Service does not receive a Heartbeat within a [Heartbeat Timeout](/encyclopedia/detecting-activity-failures#heartbeat-timeout) time period, the Activity will be considered as timed out and another [Activity Task Execution](/workers#activity-task-execution) may be scheduled according to the Retry Policy.

Activity Cancellations are delivered to Activities from the Temporal Service when they Heartbeat.
Activities that don't Heartbeat can't get notified of Cancellation requests.

Heartbeats may not always be sent to the Temporal Service—they may be [throttled](/encyclopedia/detecting-activity-failures#throttling) by the Worker.
Heartbeat throttling may lead to Cancellation getting delivered later than expected.

To Heartbeat an Activity Execution in TypeScript, call the [`heartbeat()`](https://typescript.temporal.io/api/namespaces/activity#heartbeat) function from the Activity implementation.

```typescript
export async function myActivity(): Promise<void> {
  for (let progress = 1; progress <= 1000; ++progress) {
    // Do something that takes time
    await sleep('1s');

    heartbeat();
  }
}
```

An Activity may optionally checkpoint its progression, by providing a `details` argument to the [`heartbeat()`](https://typescript.temporal.io/api/namespaces/activity#heartbeat) function.
Should the Activity Execution times out and gets retried, then the Temporal Server will provide the `details` from the last Heartbeat it received to the next Activity Execution.
This can be used to allow the Activity to efficiently resume its work.

```typescript
export async function myActivity(): Promise<void> {
  // Resume work from latest heartbeat, if there's one, or start from 1 otherwise
  const startingPoint = activityInfo().heartbeatDetails?.progress ?? 1;

  for (let progress = startingPoint; progress <= 1000; ++progress) {
    // Do something that takes time
    await sleep('1s');

    heartbeat({ progress });
  }
}
```

## Activity Heartbeat Timeout {#activity-heartbeat-timeout}

**How to set a Heartbeat Timeout using the Temporal TypeScript SDK**

A [Heartbeat Timeout](/encyclopedia/detecting-activity-failures#heartbeat-timeout) works in conjunction with [Activity Heartbeats](/encyclopedia/detecting-activity-failures#activity-heartbeat).
If the Temporal Server doesn't receive a Heartbeat before expiration of the Heartbeat Timeout, the Activity is considered as timed out and another [Activity Task Execution](/workers#activity-task-execution) may be scheduled according to the Retry Policy.

To set an Activity's Heartbeat Timeout in TypeScript, set the [`ActivityOptions.heartbeatTimeout`](https://typescript.temporal.io/api/interfaces/common.ActivityOptions#heartbeattimeout) property when creating the corresponding Activity proxy functions using the [`proxyActivities()`](https://typescript.temporal.io/api/namespaces/workflow#proxyactivities) API.

```typescript
const { myLongRunningActivity } = proxyActivities<typeof activities>({
  // ...
  heartbeatTimeout: '30s',
});
```
